from datetime import datetime
import random

from flask import request, abort, make_response, jsonify, current_app, session

from info.modules.passport import passport_dp
from info.utils.captcha.captcha import captcha
from info import redis_store, db
from info.constants import IMAGE_CODE_REDIS_EXPIRES
from info.response_code import RET
import re
from info.models import User
from info.lib.yuntongxun.sms import CCP


@passport_dp.route('/logout', methods=["POST"])
def logout():
    session.pop("user_id", "")
    session.pop("mobile", "")
    session.pop("nick_name", "")

    return jsonify(errno=RET.OK, errmsg="退出成功")


@passport_dp.route('/login', methods=["POST"])
def login():
    param_dict = request.json
    mobile = param_dict.get("mobile")
    password = param_dict.get("password")

    if not all([mobile, password]):
        current_app.logger.error("参数不足")
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    result = re.match("1[3578][0-9]{9}", mobile)
    if not result:
        return jsonify(errno=RET.PARAMERR, errmsg="手机号码格式错误")

    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询用户对象异常")
    if not user:
        return jsonify(errno=RET.USERERR, errmsg="用户未注册")

    if not user.check_passowrd(password):
        return jsonify(errno=RET.DATAERR, errmsg="密码错误")
    user.last_login = datetime.now()
    try:
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存用户对象异常")

    session["user_id"] = user.id
    session["mobile"] = user.mobile
    session["nick_name"] = user.nick_name

    return jsonify(errno=RET.OK, errmsg="登陆成功")


@passport_dp.route('/sms_code', methods=["POST"])
def send_sms_code():
    # 获取请求,手机号码,验证码内容,验证码编号
    print("收到ajax请求")
    param_dict = request.json
    mobile = param_dict.get("mobile")
    image_code = param_dict.get("image_code")
    image_code_id = param_dict.get("image_code_id")
    # 判断获取的值是否为空
    if not all([mobile, image_code, image_code_id]):
        current_app.logger.error("参数不足")
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    # 判断手机号码的格式是否正确
    result = re.match("1[3578][0-9]{9}", mobile)
    if not result:
        return jsonify(errno=RET.PARAMERR, errmsg="手机号码格式错误")
    try:
        real_image_code = redis_store.get("Image_Code_Id_%s" % image_code_id)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询redis图形验证码异常")
    if real_image_code:
        redis_store.delete("Image_Code_Id_%s" % image_code_id)
    else:
        return jsonify(errno=RET.NODATA, errmsg="图片验证码以过期")
    if real_image_code.lower() != image_code.lower():
        return jsonify(errno=RET.DATAERR, errmsg="图片验证码填写错误")
    # 判断手机号是否已被注册
    try:
        user = User.query.filter(User.mobile == mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="查询用户数据异常")
    if user:
        return jsonify(errno=RET.DATAEXIST, errmsg="手机号码已被注册")

    real_sms_code = random.randint(0, 999999)
    real_sms_code = "%06d" % real_sms_code
    try:
        result = CCP().send_template_sms(mobile, {real_sms_code, 5}, 1)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR, errmsg="云通信发送短信验证码异常")
    if result == -1:
        return jsonify(errno=RET.THIRDERR, errmsg="云通信发送短信验证码异常")
    redis_store.setex("SMS_Code_%s" % mobile, IMAGE_CODE_REDIS_EXPIRES, real_sms_code )

    return jsonify(errno=RET.OK, errmsg="短信验证码发送成功")


@passport_dp.route('/image_code')
def get_image_code():
    code_id = request.args.get("code_id")

    if not code_id:
        print("uuid is null")
        return abort(404)

    image_name, real_image_code, image_data = captcha.generate_captcha()
    redis_store.setex("Image_Code_Id_%s" % code_id, IMAGE_CODE_REDIS_EXPIRES, real_image_code)

    response = make_response(image_data)
    response.headers["Content-Type"] = 'image/jpg'

    return response


@passport_dp.route('/register', methods=["POST"])
def register():
    param_dict = request.json
    mobile = param_dict.get("mobile")
    smscode = param_dict.get("smscode")
    password = param_dict.get("password")

    if not all([mobile, smscode, password]):
        current_app.logger.error("参数不足")
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    result = re.match(r"1[3578][0-9]{9}", mobile)
    if not result:
        return jsonify(errno=RET.PARAMERR, errmsg="参数不足")
    try:
        real_sms_code = redis_store.get("SMS_Code_%s" % mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR, errmsg="数据库查询错误")
    if real_sms_code:
        redis_store.delete("SMS_Code_%s" % mobile)
    else:
        return jsonify(errno=RET.NODATA, errmsg="短信验证码以过期")
    if real_sms_code != smscode:
        return jsonify(errno=RET.DATAERR, errmsg="短信验证码输入有误")
    user = User()
    user.nick_name = mobile
    user.mobile = mobile
    # 密码加密方法一:
    # user.set_password_hash(password)
    # 密码加密方法二:
    # python可以给不存在的属性赋值,给password属性赋值的时候会调用getter方法
    user.password = password

    user.last_login = datetime.now()
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR, errmsg="保存用户对象异常")

    session["user_id"] = user.id
    session["nick_name"] = user.nick_name
    session["mobile"] = user.mobile

    return jsonify(errno=RET.OK, errmsg="注册成功")


